<html>
<head><meta charset="utf-8"><title>Stabilizing `Step` · t-libs · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/index.html">t-libs</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html">Stabilizing `Step`</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="246808006"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/246808006" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Pratt <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#246808006">(Jul 22 2021 at 04:34)</a>:</h4>
<p>Aside from my recent-ish change making it safe to implement (<a href="https://github.com/rust-lang/rust/issues/83772">#83772</a> which was merged on May 30), the <code>Step</code> trait (<a href="https://github.com/rust-lang/rust/issues/42168">#42168</a>) has been unchanged since <a href="https://github.com/rust-lang/rust/issues/69659">#69659</a> (14 months ago). Does it make sense to stabilize this as-is? Without <code>TrustedStep</code> of course, as that requires min-specialization.</p>



<a name="246916786"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/246916786" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Pratt <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#246916786">(Jul 22 2021 at 23:18)</a>:</h4>
<p>Bueller?</p>



<a name="246920135"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/246920135" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#246920135">(Jul 23 2021 at 00:16)</a>:</h4>
<p>I would like to see this stablized. I have a library that would benefit from being able to impl Step (and does, behind a crate feature).</p>



<a name="247094751"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247094751" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247094751">(Jul 24 2021 at 21:29)</a>:</h4>
<p>Step was also unchanged for a while before those changes, so I'm not really convinced that just the time means that it's good to go.</p>
<p>There's never been an RFC, right?  It seems to me like it might be worth an RFC arguing that this form is correct, and more generally that a trait here at all is correct.</p>
<p>For example, one possible alternative would be to make <code>Range</code> and friends <code>#[fundamental]</code> so that num could just implement <code>Iterator for Range&lt;BigInt&gt;</code> directly itself.</p>
<p>Other possible things include whether there are types that should only go forward, and thus there should be Step for Iterator and BackwardStep for DoubleEndedIterator, for example.</p>



<a name="247108033"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247108033" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Pratt <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247108033">(Jul 25 2021 at 04:29)</a>:</h4>
<p>What would be the negatives of it being <code>#[fundamental]</code>?</p>



<a name="247108090"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247108090" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Pratt <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247108090">(Jul 25 2021 at 04:30)</a>:</h4>
<p>But no, as far as I know there's never been an RFC. Something like <code>BackwardStep</code> (bikeshedding apart) would already be possible by just calling <code>.backward()</code>, not <code>.forward()</code>, no?</p>



<a name="247108105"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247108105" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Pratt <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247108105">(Jul 25 2021 at 04:31)</a>:</h4>
<p>^^ negatives from a lang/libs perspective. There are certainly negatives from a user perspective (like requiring multiple implementations for the same output type)</p>



<a name="247112302"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247112302" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> inquisitivecrystal <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247112302">(Jul 25 2021 at 06:47)</a>:</h4>
<p>The main negative as far as I know is that it means that future impls are a breaking change?</p>



<a name="247112307"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247112307" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> inquisitivecrystal <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247112307">(Jul 25 2021 at 06:47)</a>:</h4>
<p>Which is actually a pretty big negative.</p>



<a name="247112311"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247112311" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> inquisitivecrystal <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247112311">(Jul 25 2021 at 06:47)</a>:</h4>
<p>It basically makes it impossible to implement new standard library traits for it.</p>



<a name="247112362"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247112362" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> inquisitivecrystal <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247112362">(Jul 25 2021 at 06:49)</a>:</h4>
<p>I'd think that a new trait would be less of a big club.</p>



<a name="247113063"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247113063" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Pratt <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247113063">(Jul 25 2021 at 07:10)</a>:</h4>
<p>Just thinking, having the various range types be fundamental would prohibit implementing <code>Copy</code>, would it not? Barring specialization or overlapping marker traits presumably.</p>



<a name="247113243"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247113243" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> inquisitivecrystal <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247113243">(Jul 25 2021 at 07:15)</a>:</h4>
<p>I believe it would, though I'm not an expert.</p>



<a name="247130819"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247130819" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247130819">(Jul 25 2021 at 15:18)</a>:</h4>
<p>I'd like not to preclude implementing Copy on ranges, from reading its past discussions I might have a design that satisfies all parties but I need to think about it some more and actually write it up</p>



<a name="247140988"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247140988" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247140988">(Jul 25 2021 at 19:30)</a>:</h4>
<p><span class="user-mention silent" data-user-id="245610">Jacob Pratt</span> <a href="#narrow/stream/219381-t-libs/topic/Stabilizing.20.60Step.60/near/247108090">said</a>:</p>
<blockquote>
<p>Something like <code>BackwardStep</code> (bikeshedding apart) would already be possible by just calling <code>.backward()</code>, not <code>.forward()</code>, no?</p>
</blockquote>
<p>But what if there's a type that can only step forward, and thus <code>backward</code> isn't implementable?  Right now <code>Step</code> implies <code>DoubleEndedIterator</code>; there's no way to be <em>only</em> <code>Iterator</code>.</p>



<a name="247141079"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247141079" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247141079">(Jul 25 2021 at 19:32)</a>:</h4>
<p><span class="user-mention silent" data-user-id="417924">inquisitivecrystal</span> <a href="#narrow/stream/219381-t-libs/topic/Stabilizing.20.60Step.60/near/247112311">said</a>:</p>
<blockquote>
<p>It basically makes it impossible to implement new standard library traits for it.</p>
</blockquote>
<p>Well, implementations can be added, but only at the same time as the new trait is added.  If something is forgotten at stabilization time, it can never be added later.</p>
<p>(<code>#[fundamental]</code> is a big hammer, so it's not obvious to me that it would be the <em>correct</em> solution, but given the large number of trait designs we've been through I think it's at least worth seriously looking at as an alternative to avoid needing to pick the One True Step Trait.)</p>



<a name="247142704"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247142704" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Pratt <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247142704">(Jul 25 2021 at 20:11)</a>:</h4>
<p>Are you thinking something along the lines of splitting <code>Step</code> into <code>ForwardStep</code> and <code>BackwardStep</code>? I'm not sure how <code>steps_between</code> would fit into a spit off the top of my head, but I suppose it could be done.</p>



<a name="247142706"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247142706" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Pratt <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247142706">(Jul 25 2021 at 20:11)</a>:</h4>
<p><code>DoubleEndedIterator</code> and whatnot could be implemented automatically when both traits are implemented.</p>



<a name="247147537"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247147537" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247147537">(Jul 25 2021 at 21:52)</a>:</h4>
<p>for <code>steps_between</code>, maybe have a <code>MeasurableStep</code> trait?</p>



<a name="247147547"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247147547" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247147547">(Jul 25 2021 at 21:53)</a>:</h4>
<p>or <code>MeasureSteps</code></p>



<a name="247149426"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247149426" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> inquisitivecrystal <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247149426">(Jul 25 2021 at 22:43)</a>:</h4>
<p><span class="user-mention silent" data-user-id="125270">scottmcm</span> <a href="#narrow/stream/219381-t-libs/topic/Stabilizing.20.60Step.60/near/247141079">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="417924">inquisitivecrystal</span> <a href="#narrow/stream/219381-t-libs/topic/Stabilizing.20.60Step.60/near/247112311">said</a>:</p>
<blockquote>
<p>It basically makes it impossible to implement new standard library traits for it.</p>
</blockquote>
<p>Well, implementations can be added, but only at the same time as the new trait is added.  If something is forgotten at stabilization time, it can never be added later.</p>
<p>(<code>#[fundamental]</code> is a big hammer, so it's not obvious to me that it would be the <em>correct</em> solution, but given the large number of trait designs we've been through I think it's at least worth seriously looking at as an alternative to avoid needing to pick the One True Step Trait.)</p>
</blockquote>
<p>It feels to me like this is essentially technical debt. Or, that's not quite the right term. But we'd be sacrificing future flexibility because we don't want to figure out how to design the API now.</p>



<a name="247149479"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247149479" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> inquisitivecrystal <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247149479">(Jul 25 2021 at 22:45)</a>:</h4>
<p>It feels a bit silly. It's like... working out the correct API may not be easy, but it's still our job to do it, somehow.</p>



<a name="247149492"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247149492" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> inquisitivecrystal <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247149492">(Jul 25 2021 at 22:45)</a>:</h4>
<p>I would consider it less bad to have an incorrectly desgined <code>Step</code> API than to lock future rust stdlib developers out of the flexibility that comes from being able to implement traits.</p>



<a name="247161749"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247161749" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Pratt <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247161749">(Jul 26 2021 at 04:17)</a>:</h4>
<p>(deleted)</p>



<a name="247161921"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247161921" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Pratt <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247161921">(Jul 26 2021 at 04:21)</a>:</h4>
<p><span class="user-mention" data-user-id="229517">@Jacob Lifshay</span> the problem is <code>steps_between</code> is for moving forwards, not backwards</p>



<a name="247163647"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247163647" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247163647">(Jul 26 2021 at 05:03)</a>:</h4>
<p><span class="user-mention silent" data-user-id="245610">Jacob Pratt</span> <a href="#narrow/stream/219381-t-libs/topic/Stabilizing.20.60Step.60/near/247161921">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="229517">Jacob Lifshay</span> the problem is <code>steps_between</code> is for moving forwards, not backwards</p>
</blockquote>
<p>?? it should be for counting the number of steps needed to move between <code>a</code> and <code>b</code>, <code>steps_between(&amp;a, &amp;b)</code>. it counts the number of steps to move forward from <code>a</code> to get to <code>b</code>; it also counts the number of steps to move backward from <code>b</code> to get to <code>a</code>. So, it's useful for both stepping forwards and for stepping backwards</p>



<a name="247164186"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247164186" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Pratt <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247164186">(Jul 26 2021 at 05:15)</a>:</h4>
<p>I see what you mean, but why would that be a separate trait?</p>



<a name="247164241"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247164241" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Pratt <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247164241">(Jul 26 2021 at 05:17)</a>:</h4>
<p>Right now there's an invariant "<code>steps_between(&amp;a, &amp;b) == None</code> if <code>a &gt; b</code>" which obviously couldn't be generalized to <code>ForwardStep</code> and <code>BackwardStep</code> traits. You <em>could</em> just flip the ordering of everything, but then it's not clear what should be used for <code>TrustedLen</code> impls.</p>



<a name="247166548"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247166548" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247166548">(Jul 26 2021 at 06:11)</a>:</h4>
<p><span class="user-mention silent" data-user-id="245610">Jacob Pratt</span> <a href="#narrow/stream/219381-t-libs/topic/Stabilizing.20.60Step.60/near/247164186">said</a>:</p>
<blockquote>
<p>I see what you mean, but why would that be a separate trait?</p>
</blockquote>
<p>because <code>steps_between</code> is useful for things that can only step forwards, or things that can only step backwards, or things that can step either direction...it is a more general concept than just <code>StepForward</code> or <code>StepBackward</code>.</p>



<a name="247166872"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247166872" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247166872">(Jul 26 2021 at 06:17)</a>:</h4>
<p>Additionally, by having <code>steps_between</code> be in a separate trait, you don't ever have to worry that <code>StepForward::steps_between</code> and <code>StepBackward::steps_between</code> might behave differently, they both refer to <code>MeasureStep::steps_between</code> (though I'm not necessarily advocating that <code>MeasureStep</code> should be a super-trait of the other <code>Step*</code> traits...)</p>



<a name="247166966"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247166966" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Pratt <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247166966">(Jul 26 2021 at 06:19)</a>:</h4>
<p>It likely wouldn't be clear what a step is if it's a separate trait, as there's two directions it can go (right now it's clearly only forwards).</p>



<a name="247166978"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247166978" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Pratt <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247166978">(Jul 26 2021 at 06:19)</a>:</h4>
<p>Honestly I don't see a use case for a backwards-only implementation of <code>Step</code> — what would require such a thing?</p>



<a name="247167037"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247167037" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Pratt <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247167037">(Jul 26 2021 at 06:20)</a>:</h4>
<p>because right now I'm debating something I can't envision a use for, which seems...useless</p>



<a name="247169636"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247169636" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247169636">(Jul 26 2021 at 07:07)</a>:</h4>
<p><span class="user-mention silent" data-user-id="245610">Jacob Pratt</span> <a href="#narrow/stream/219381-t-libs/topic/Stabilizing.20.60Step.60/near/247166978">said</a>:</p>
<blockquote>
<p>Honestly I don't see a use case for a backwards-only implementation of <code>Step</code> — what would require such a thing?</p>
</blockquote>
<p>hmm, how about something like git's commit graph, but without merge commits: you could easily step from a particular revision to an older revision by just following parent links, however you couldn't go from an older revision to a newer one because there could be multiple revisions that all have the same parent and you can't decide which one to use. You could implement <code>BackwardStep</code> and <code>steps_between</code>, but not <code>ForwardStep</code>.</p>



<a name="247169721"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247169721" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247169721">(Jul 26 2021 at 07:09)</a>:</h4>
<p>Another example where you could implement <code>BackwardStep</code> but not <code>ForwardStep</code> is for a reversed version of a forward-only type.</p>



<a name="247170277"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247170277" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Pratt <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247170277">(Jul 26 2021 at 07:18)</a>:</h4>
<p>While you could obviously use <code>Step</code> and its methods on its own, the purpose <em>is</em> for the various <code>Range*</code> types, is it not? Unless there's plans to have a backwards-by-default type, wouldn't this only be for the likely uncommon case of calling methods directly?</p>



<a name="247170821"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247170821" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Pratt <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247170821">(Jul 26 2021 at 07:26)</a>:</h4>
<p>Basically there's no "reverse iterator" anywhere in stdlib</p>



<a name="247209419"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247209419" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247209419">(Jul 26 2021 at 14:27)</a>:</h4>
<p><span class="user-mention silent" data-user-id="245610">Jacob Pratt</span> <a href="#narrow/stream/219381-t-libs/topic/Stabilizing.20.60Step.60/near/247170821">said</a>:</p>
<blockquote>
<p>Basically there's no "reverse iterator" anywhere in stdlib</p>
</blockquote>
<p>ok, in that case, <code>Step</code> can be split into <code>ForwardStep</code> and <code>BidirectionalStep</code>:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">pub</span><span class="w"> </span><span class="k">trait</span><span class="w"> </span><span class="n">ForwardStep</span>: <span class="nb">Clone</span> <span class="o">+</span><span class="w"> </span><span class="nb">PartialOrd</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">fn</span> <span class="nf">steps_between</span><span class="p">(</span><span class="n">start</span>: <span class="kp">&amp;</span><span class="nc">Self</span><span class="p">,</span><span class="w"> </span><span class="n">end</span>: <span class="kp">&amp;</span><span class="nc">Self</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Option</span><span class="o">&lt;</span><span class="kt">usize</span><span class="o">&gt;</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="k">fn</span> <span class="nf">forward_checked</span><span class="p">(</span><span class="n">start</span>: <span class="nc">Self</span><span class="p">,</span><span class="w"> </span><span class="n">count</span>: <span class="kt">usize</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Option</span><span class="o">&lt;</span><span class="bp">Self</span><span class="o">&gt;</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="k">fn</span> <span class="nf">forward</span><span class="p">(</span><span class="n">start</span>: <span class="nc">Self</span><span class="p">,</span><span class="w"> </span><span class="n">count</span>: <span class="kt">usize</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">Self</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="o">..</span><span class="p">.</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="k">unsafe</span><span class="w"> </span><span class="k">fn</span> <span class="nf">forward_unchecked</span><span class="p">(</span><span class="n">start</span>: <span class="nc">Self</span><span class="p">,</span><span class="w"> </span><span class="n">count</span>: <span class="kt">usize</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">Self</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="o">..</span><span class="p">.</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">pub</span><span class="w"> </span><span class="k">trait</span><span class="w"> </span><span class="n">BidirectionalStep</span>: <span class="nc">ForwardStep</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">fn</span> <span class="nf">backward_checked</span><span class="p">(</span><span class="n">start</span>: <span class="nc">Self</span><span class="p">,</span><span class="w"> </span><span class="n">count</span>: <span class="kt">usize</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Option</span><span class="o">&lt;</span><span class="bp">Self</span><span class="o">&gt;</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="k">fn</span> <span class="nf">backward</span><span class="p">(</span><span class="n">start</span>: <span class="nc">Self</span><span class="p">,</span><span class="w"> </span><span class="n">count</span>: <span class="kt">usize</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">Self</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="o">..</span><span class="p">.</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="k">unsafe</span><span class="w"> </span><span class="k">fn</span> <span class="nf">backward_unchecked</span><span class="p">(</span><span class="n">start</span>: <span class="nc">Self</span><span class="p">,</span><span class="w"> </span><span class="n">count</span>: <span class="kt">usize</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">Self</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="o">..</span><span class="p">.</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="247212338"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247212338" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247212338">(Jul 26 2021 at 14:47)</a>:</h4>
<p>reverse iterator/step can be added later:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="cp">#[unstable(feature = </span><span class="s">"reverse_iter"</span><span class="cp">)]</span><span class="w"></span>
<span class="k">pub</span><span class="w"> </span><span class="k">trait</span><span class="w"> </span><span class="n">ReverseStep</span>: <span class="nb">Clone</span> <span class="o">+</span><span class="w"> </span><span class="nb">PartialOrd</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="sd">/// get `(start..end).len()`</span>
<span class="w">    </span><span class="sd">/// if `steps_between(&amp;a, &amp;b) == Some(N)`, then</span>
<span class="w">    </span><span class="sd">/// it must be the case that `a == backward(b, N)`</span>
<span class="w">    </span><span class="k">fn</span> <span class="nf">steps_between</span><span class="p">(</span><span class="n">start</span>: <span class="kp">&amp;</span><span class="nc">Self</span><span class="p">,</span><span class="w"> </span><span class="n">end</span>: <span class="kp">&amp;</span><span class="nc">Self</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Option</span><span class="o">&lt;</span><span class="kt">usize</span><span class="o">&gt;</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="k">fn</span> <span class="nf">backward_checked</span><span class="p">(</span><span class="n">start</span>: <span class="nc">Self</span><span class="p">,</span><span class="w"> </span><span class="n">count</span>: <span class="kt">usize</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Option</span><span class="o">&lt;</span><span class="bp">Self</span><span class="o">&gt;</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="k">fn</span> <span class="nf">backward</span><span class="p">(</span><span class="n">start</span>: <span class="nc">Self</span><span class="p">,</span><span class="w"> </span><span class="n">count</span>: <span class="kt">usize</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">Self</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="o">..</span><span class="p">.</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="k">unsafe</span><span class="w"> </span><span class="k">fn</span> <span class="nf">backward_unchecked</span><span class="p">(</span><span class="n">start</span>: <span class="nc">Self</span><span class="p">,</span><span class="w"> </span><span class="n">count</span>: <span class="kt">usize</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">Self</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="o">..</span><span class="p">.</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span>: <span class="nc">BidirectionalStep</span><span class="o">&gt;</span><span class="w"> </span><span class="n">ReverseStep</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">T</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="o">..</span><span class="p">.</span><span class="w"> </span><span class="p">}</span><span class="w"></span>

<span class="cp">#[unstable(feature = </span><span class="s">"reverse_iter"</span><span class="cp">)]</span><span class="w"></span>
<span class="k">pub</span><span class="w"> </span><span class="k">trait</span><span class="w"> </span><span class="n">ReverseIterator</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">type</span> <span class="nc">Item</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="k">fn</span> <span class="nf">next_back</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Option</span><span class="o">&lt;</span><span class="bp">Self</span>::<span class="n">Item</span><span class="o">&gt;</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="o">..</span><span class="p">.</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span>: <span class="nc">BidirectionalIterator</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="o">?</span><span class="nb">Sized</span><span class="o">&gt;</span><span class="w"> </span><span class="n">ReverseIterator</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">T</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="o">..</span><span class="p">.</span><span class="w"> </span><span class="p">}</span><span class="w"></span>

<span class="c1">// maybe modify Iterator::rev() to use ReverseIterator bound instead of BidirectionalIterator once specialization is good enough?</span>
</code></pre></div>



<a name="247253138"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247253138" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Pratt <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247253138">(Jul 26 2021 at 19:56)</a>:</h4>
<p>^^ Anyone else have thoughts on that? It seems like a reasonable change to make that would assuage concerns.</p>



<a name="247253982"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247253982" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> The 8472 <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247253982">(Jul 26 2021 at 20:02)</a>:</h4>
<p>What mathematical structure makes it easy to only calculate steps in one direction but still have a way to calculate steps between, since that requires subtraction?</p>



<a name="247255266"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247255266" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Pratt <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247255266">(Jul 26 2021 at 20:11)</a>:</h4>
<p>A single linked list would fit that description. You'd need some additional info to calculate the number of steps between two nodes efficiently, but there would be no way to iterate in reverse for obvious reasons.</p>



<a name="247255905"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247255905" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> The 8472 <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247255905">(Jul 26 2021 at 20:16)</a>:</h4>
<p>you would need to be able to calculate the steps between <em>any two nodes</em>, so that would only allow a linked list with the index encoded in every node, which kind of voids the benefits of a linked list, no?</p>



<a name="247255973"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247255973" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> The 8472 <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247255973">(Jul 26 2021 at 20:17)</a>:</h4>
<p>And it wouldn't have an efficient <code>nth</code> implementation.</p>



<a name="247256010"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247256010" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Pratt <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247256010">(Jul 26 2021 at 20:17)</a>:</h4>
<p>Like I said it wouldn't be efficient, but you <em>could</em> just walk the list.</p>



<a name="247256034"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247256034" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Pratt <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247256034">(Jul 26 2021 at 20:17)</a>:</h4>
<p>I know git commits were mentioned earlier.</p>



<a name="247256040"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247256040" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> The 8472 <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247256040">(Jul 26 2021 at 20:17)</a>:</h4>
<p>At that point you could just use an iterator.</p>



<a name="247256418"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247256418" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> The 8472 <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247256418">(Jul 26 2021 at 20:20)</a>:</h4>
<p>git history doesn't work because it's a graph not a sequence.</p>



<a name="247257108"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247257108" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> The 8472 <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247257108">(Jul 26 2021 at 20:26)</a>:</h4>
<p>Hrrm... the <code>Step</code> trait has <code>PartialOrd</code> as bound but doesn't talk about what happens when you have something that doesn't have total order.</p>



<a name="247257416"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247257416" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> The 8472 <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247257416">(Jul 26 2021 at 20:29)</a>:</h4>
<p>So technically a git commit <code>Range</code> and <code>Step</code> would be possible (even though inefficient) but could lead to surprising results. E.g. you could find that a value is <code>contain()</code>ed in  range but iterating through the whole range will never visit it because you're walking down a different branch.</p>



<a name="247258795"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247258795" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247258795">(Jul 26 2021 at 20:41)</a>:</h4>
<p>git commits won't work because there is no unambiguous parent for every commit, some have multiple parents.<br>
If git's commit graph were modified to enforce that every commit can have either 0 or 1 parent commit (thereby excluding merge commits as mentioned earlier) and the graph is required to be a DAG (already a requirement for git iirc), then comparing can be done where they're equal if both inputs are the same node, and one is less/greater than another if it is an ancestor/descendent node of the other node, otherwise they are incomparable. That comparison scheme is consistent and ranges are either not well defined (endpoints are two unrelated nodes, similar to <code>NaN..=NaN</code>) or ranges include only the nodes that are descendents of one and ancestors of the other endpoint (and also the endpoint nodes themselves as appropriate), all such nodes can be reached by walking the parent node chain.</p>



<a name="247259272"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247259272" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> The 8472 <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247259272">(Jul 26 2021 at 20:44)</a>:</h4>
<p>If you specify a range of git commits then you can search for possible paths between those nodes. everything along all possible paths between them then would fall into this "range". And it can be stepped through if you choose any particular path, e.g. the shortest one.<br>
That's all that the current bounds require (Clone + PartialOrd). You'd have to do some expensive computation on each step or cache it somewhere, but technically it would be allowed. I just think it would be a bad idea.</p>



<a name="247259505"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247259505" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247259505">(Jul 26 2021 at 20:46)</a>:</h4>
<p>so, assuming <code>contain</code>'s code is implemented correctly as <code>begin &lt;= x &amp;&amp; x &lt; end</code> for <code>Range</code> (and similarly for other range types), it will always return the correct result for the above <code>PartialOrd</code> definition I stated.</p>



<a name="247259860"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247259860" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> The 8472 <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247259860">(Jul 26 2021 at 20:49)</a>:</h4>
<p>My point was that <code>Range::contain(x) == true</code> but  <code>while let Some(y) = Step::forward_checked(1) { if x == y {prinln!("found!")} }</code> will never print.</p>



<a name="247260157"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247260157" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> The 8472 <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247260157">(Jul 26 2021 at 20:52)</a>:</h4>
<p>aiui <code>PartialOrd</code>'s requirements do not preclude diamonds.</p>



<a name="247260352"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247260352" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247260352">(Jul 26 2021 at 20:53)</a>:</h4>
<p><span class="user-mention silent" data-user-id="330154">The 8472</span> <a href="#narrow/stream/219381-t-libs/topic/Stabilizing.20.60Step.60/near/247259272">said</a>:</p>
<blockquote>
<p>If you specify a range of git commits then you can search for possible paths between those nodes. everything along all possible paths between them then would fall into this "range". And it can be stepped through if you choose any particular path, e.g. the shortest one.<br>
That's all that the current bounds require (Clone + PartialOrd). You'd have to do some expensive computation on each step or cache it somewhere, but technically it would be allowed. I just think it would be a bad idea.</p>
</blockquote>
<p>well, I'd say it's your own fault for implementing any <code>Step</code> trait for git commits, since <code>forward</code> has to arbitrarily choose one path since which path to follow is ambiguous, of course range iteration will not be consistent. For the modified git commit graph without merge commits, range iteration is consistent since there is always either 0 or 1 path between nodes, so no arbitrary choice is needed.</p>



<a name="247260722"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247260722" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247260722">(Jul 26 2021 at 20:56)</a>:</h4>
<p>basically, I'm saying <code>Step</code> should require that there is always 0 or 1 valid path(s) between any two values</p>



<a name="247260853"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247260853" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> The 8472 <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247260853">(Jul 26 2021 at 20:57)</a>:</h4>
<p>I don't disagree, I was merely pointing out that it currently isn't forbidding that.</p>



<a name="247261045"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247261045" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247261045">(Jul 26 2021 at 20:59)</a>:</h4>
<p>though <code>steps_between</code> may have to be modified to distinguish between no path and path with <code>count &gt; usize::MAX</code></p>



<a name="247261359"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247261359" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> The 8472 <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247261359">(Jul 26 2021 at 21:00)</a>:</h4>
<p>Or we require <code>Ord</code>, then there is a total order which implies only one path.</p>



<a name="247262542"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247262542" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247262542">(Jul 26 2021 at 21:05)</a>:</h4>
<p>just requiring <code>Ord</code> may be easier, since we wouldn't have to define what <code>(a..=b).collect()</code> returns when <code>a.partial_ord(&amp;b) == None</code></p>



<a name="247272490"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247272490" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247272490">(Jul 26 2021 at 22:32)</a>:</h4>
<p><span class="user-mention silent" data-user-id="229517">Jacob Lifshay</span> <a href="#narrow/stream/219381-t-libs/topic/Stabilizing.20.60Step.60/near/247261045">said</a>:</p>
<blockquote>
<p>though <code>steps_between</code> may have to be modified to distinguish between no path and path with <code>count &gt; usize::MAX</code></p>
</blockquote>
<p>Hmm, I opened this issue back in 2018, and it sounds like it might still be a problem: <a href="https://github.com/rust-lang/rust/issues/48117">https://github.com/rust-lang/rust/issues/48117</a></p>



<a name="247288570"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Stabilizing%20%60Step%60/near/247288570" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Pratt <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Stabilizing.20.60Step.60.html#247288570">(Jul 27 2021 at 02:48)</a>:</h4>
<p>@scottmcm these two things are no longer true, though</p>
<blockquote>
<p>But it also uses <code>None</code> for unimplemented</p>
<p>And as a result, <code>Range</code> needs to return <code>(0, None)</code> when it gets <code>None</code></p>
</blockquote>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>